<template>
  <div class="map-area-wrapper">
    <div :id="props.id" class="map-area"></div>
    <div class="map-area-tools">
      <a-button
        v-if="tools.includes('clear')"
        type="primary"
        size="mini"
        @click="handleResetMake"
      >
        重画
      </a-button>
    </div>
    <div class="map-area-search">
      <a-input-search
        class="search-input"
        :style="{ width: '320px', marginBottom: '10px' }"
        placeholder="请输入地址搜索"
        search-button
        @search="handleSearch"
      />
      <div :id="searchId" class="search-pannel"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import {
    onUnmounted,
    onMounted,
    withDefaults,
    defineProps,
    nextTick,
    defineExpose,
  } from 'vue';
  import { random } from 'lodash';
  import { initMapFile } from '@/utils/initMap';

  interface DataItem {
    id: string;
    paths: number[][];
  }
  interface Props {
    id?: string;
    canEdit?: boolean;
    tools: string[];
  }
  const props = withDefaults(defineProps<Props>(), {
    id: 'map-container',
    tools: () => {
      return [];
    },
  });

  let map: any = null;
  let initLoading = false;
  let lineArrLocal: DataItem[] = [];
  let areaMapObj: any = {};
  let polyEditor: any = null;
  let placeSearch: any = null;
  const searchId = `search-${Date.now()}-${random(1000, 9999)}`;

  const initMap = () => {
    map = new window.AMap.Map(props.id, {
      resizeEnable: true,
      zoom: 17,
    });

    placeSearch = new window.AMap.PlaceSearch({
      map,
      panel: searchId,
      autoFitView: true,
    }); //
  };

  const initMapLoader = () => {
    return new Promise<void>((resolve, reject) => {
      if (initLoading) {
        resolve();
        return;
      }
      if (!window.AMap) {
        initLoading = true;
        initMapFile()
          .then((res) => {
            initLoading = false;
            window.AMap = res;
            initMap();
            resolve();
          })
          .catch((e) => {
            console.log(e);
            reject(e);
          });
      } else {
        if (!map) {
          initMap();
        }
        resolve();
      }
    });
  };

  const setPath = () => {
    lineArrLocal.forEach((m) => {
      areaMapObj[`a_${m.id}`] = new window.AMap.Polygon({
        path: m.paths,
        extData: {
          id: m.id,
        },
      });
    });

    const areaObjList = Object.keys(areaMapObj).map((t) => {
      return areaMapObj[t];
    });

    map.add(areaObjList);
    map.setFitView();
  };

  const handleSearch = (val: string) => {
    if (placeSearch) {
      placeSearch.search(val);
    }
  };

  const setArea = (list: DataItem[]) => {
    if (map) {
      map.clearMap();

      areaMapObj = {};
      if (list?.length) {
        lineArrLocal = list;
        setPath();
      }
    }
  };

  const addArea = () => {
    if (!map) return;
    if (!polyEditor) {
      polyEditor = new window.AMap.PolygonEditor(map);
    }
    polyEditor.close();
    polyEditor.setTarget();
    polyEditor.open();
  };

  const editArea = (paths: DataItem) => {
    if (!map) return;
    if (!polyEditor) {
      polyEditor = new window.AMap.PolygonEditor(map);
    }
    setArea([paths]);
    const area = getArea()[0];
    polyEditor.close();
    polyEditor.setTarget(area);
    polyEditor.open();
  };

  const clearArea = () => {
    if (!map) return;
    polyEditor.close();
    map.clearMap();
  };

  const handleResetMake = () => {
    clearArea();
    addArea();
  };

  const getArea = () => {
    if (!map) return null;
    return map.getAllOverlays('polygon');
  };

  defineExpose({
    addArea,
    setArea,
    clearArea,
    getArea,
    editArea,
  });

  onMounted(() => {
    nextTick(() => {
      initMapLoader();
    });
  });

  onUnmounted(() => {
    map?.destroy();
  });
</script>

<style lang="less">
  .map-area-wrapper {
    width: 100%;
    height: 100%;
    position: relative;
    .map-area-tools {
      position: absolute;
      top: 12px;
      left: 12px;
      z-index: 10;
    }
    .map-area-search {
      position: absolute;
      right: 12px;
      top: 12px;
      z-index: 10;
    }
    .search-pannel {
      position: absolute;
      right: 12px;
      top: 34px;
      height: 300px;
      width: 300px;
      z-index: 10;
      overflow: auto;
    }
    .arco-input-wrapper {
      background: #fff;
    }
  }
  .map-area {
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
</style>
